package com.grace.system.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.grace.common.constant.UserConstants;
import com.grace.common.core.text.Convert;
import com.grace.common.enums.ConfigValueTypeEnum;
import com.grace.common.enums.DataSourceType;
import com.grace.common.properties.PropertyEnum;
import com.grace.common.utils.StringUtils;
import com.grace.mybatis.annotation.DataSource;
import com.grace.redis.utils.RedisCache;
import com.grace.system.domain.SysConfig;
import com.grace.system.mapper.SysSearchConfigMapper;
import com.grace.system.service.ISysSearchConfigService;

/**
 * 配置查询
 */
@Service
public class SysSearchConfigServiceImpl implements ISysSearchConfigService {
    @Autowired
    private SysSearchConfigMapper searchConfigMapper;

    @Autowired
    private RedisCache redisCache;

    /**
     * 查询参数配置信息
     * 
     * @param config 查询参数
     * @return 参数配置信息
     */
    @Override
    @DataSource(DataSourceType.MASTER)
    public SysConfig selectConfig(SysConfig sysConfig) {
        return searchConfigMapper.selectConfig(sysConfig);
    }

    /**
     * 查询参数配置信息
     * 
     * @param configId 参数配置ID
     * @return 参数配置信息
     */
    @Override
    public SysConfig selectConfigById(Long configId) {
        SysConfig config = new SysConfig();
        config.setConfigId(configId);
        return this.selectConfig(config);
    }

    /**
     * 查询参数配置信息
     * 
     * @param configGroup 参数组
     * @param configKey   参数键名
     * @return 参数配置信息
     */
    public SysConfig selectConfigByGk(String configGroup, String configKey) {
        SysConfig config = new SysConfig();
        config.setConfigKey(configKey);
        config.setConfigGroup(configGroup);
        return searchConfigMapper.selectConfig(config);
    }

    /**
     * 根据Gk查询参数配置信息
     * 
     * @param configGroup 参数组
     * @param configKey   参数键名
     * @return 参数键值
     */
    @Override
    public String selectConfigValueByGk(String configGroup, String configKey) {
        String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configGroup, configKey)));
        if (StringUtils.isNotEmpty(configValue)) {
            return configValue;
        }
        SysConfig config = new SysConfig();
        config.setConfigKey(configKey);
        config.setConfigGroup(configGroup);
        SysConfig retConfig = searchConfigMapper.selectConfig(config);
        if (StringUtils.isNotNull(retConfig)) {
            redisCache.setCacheObject(getCacheKey(configGroup, configKey), retConfig.getConfigValue());
            return retConfig.getConfigValue();
        }
        return StringUtils.EMPTY;
    }

    /**
     * 查询参数配置列表
     * 
     * @param config 参数配置信息
     * @return 参数配置集合
     */
    @Override
    public List<SysConfig> selectConfigList(SysConfig config) {
        return searchConfigMapper.selectConfigList(config);
    }

    /**
     * 校验配置组是否唯一
     * 与配置key是否唯一
     * 
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public boolean checkConfigGkUnique(SysConfig config) {
        Long configId = StringUtils.isNull(config.getConfigId()) ? -1L : config.getConfigId();
        SysConfig info = searchConfigMapper.selectConfig(config);
        if (StringUtils.isNotNull(info) && info.getConfigId().longValue() != configId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 获取配置列表
     * 
     * @return 配置组列表
     */
    @Override
    public List<String> selectConfigGroupList() {
        return searchConfigMapper.selectConfigGroupList();
    }

    /**
     * 查询参数配置列表转Map
     * key config
     * 
     * @param config 参数配置信息
     * @return 参数配置集合
     */
    @Override
    public Map<String, SysConfig> selectConfigMap(SysConfig config) {
        List<SysConfig> sysConfigs = this.selectConfigList(config);
        Map<String, SysConfig> collect = sysConfigs.stream().collect(HashMap::new, (k, v) -> k.put(v.getConfigKey(), v),
                HashMap::putAll);
        return collect;
    }

    /**
     * 查询参数配置列表转Map
     * key value
     * 
     * @param config 参数配置信息
     * @return 参数配置集合
     */
    @Override
    public Map<String, String> selectConfigValueMap(SysConfig config) {
        List<SysConfig> sysConfigs = this.selectConfigList(config);
        Map<String, String> collect = sysConfigs.stream().collect(HashMap::new,
                (k, v) -> k.put(v.getConfigKey(), v.getConfigValue()), HashMap::putAll);
        return collect;
    }

    @Override
    public Map<String, SysConfig> selectConfigMapByGroupName(String configGroup) {
        SysConfig config = new SysConfig();
        config.setConfigGroup(configGroup);
        return this.selectConfigMap(config);
    }

    @Override
    public Map<String, String> selectConfigValueMapByGroupName(String configGroup) {
        SysConfig config = new SysConfig();
        config.setConfigGroup(configGroup);
        return this.selectConfigValueMap(config);
    }

    @Override
    public String selectConfigDefaultValue(String groupName, PropertyEnum propertyEnum) {
        String value = this.selectConfigValueByGk(groupName, propertyEnum.getValue());
        return PropertyEnum.convertTo(value, propertyEnum).toString();
    }

    /**
     * 设置cache key
     * 
     * @param configGroup 参数组
     * @param configKey   参数键
     * @return 缓存键key
     */
    private String getCacheKey(String configGroup, String configKey) {
        return ISysSearchConfigService.getCacheKey(configGroup, configKey);
    }

    /**
     * 将值转化为指定类型
     * 
     */
    @Override
    public Map<String, Object> selectConfigValueObjMap(String configGroup) {
        SysConfig config = new SysConfig();
        config.setConfigGroup(configGroup);
        List<SysConfig> sysConfigs = this.selectConfigList(config);
        Map<String, Object> collect = sysConfigs.stream().collect(HashMap::new,
                (k, v) -> k.put(v.getConfigKey(), getObjectValue(v)), HashMap::putAll);
        return collect;
    }

    /**
     * 转换为指定类型
     * 
     * @param config
     * @return
     */
    private Object getObjectValue(SysConfig config) {
        String v = config.getConfigValue();
        Object result = null;
        if (config.getConfigValueType() == ConfigValueTypeEnum.BOOLEAN.ordinal()) {
            result = "true".equals(v);
        } else if (config.getConfigValueType() == ConfigValueTypeEnum.NUMBER.ordinal()) {
            result = Integer.parseInt(v);
        } else if (config.getConfigValueType() == ConfigValueTypeEnum.FLOAT.ordinal()) {
            result = Float.parseFloat(v);
        } else if (config.getConfigValueType() == ConfigValueTypeEnum.ARRAY.ordinal()) {
            result = v.split(",");
        } else {
            result = config.getConfigValue();
        }
        return result;
    }

    @Override
    public boolean selectCaptchaEnabled(String groupName) {
        String captchaEnabled = this.selectConfigValueByGk(groupName,
                "sys.account.captchaEnabled");
        if (StringUtils.isEmpty(captchaEnabled)) {
            return true;
        }
        return Convert.toBool(captchaEnabled);
    }

}
